package com.gopay.bis.cmb.bcdl.operation;

import com.gopay.bis.cmb.bcdl.operation.util.CmbUtil;
import com.gopay.common.domain.bank.cmb.bcdl.CmbBcdlMessage;
import com.gopay.common.domain.bank.cmb.ebank.queryNtnstqry.CmbDownLoadMessage;
import com.gopay.common.domain.bank.cmb.ebank.queryNtnstqry.req.CmbNtnstqryxReq;
import com.gopay.common.domain.bank.cmb.ebank.queryNtnstqry.req.TransReqQueryInfo;
import com.gopay.common.domain.bank.cmb.ebank.queryNtnstqry.req.TransReqQueryNtnstqryx;
import com.gopay.common.domain.bank.cmb.ebank.queryNtnstqry.res.TransResQueryNtnstqryz;
import com.gopay.common.util.DateUtils;
import com.gopay.common.util.HttpTransport;
import com.gopay.common.util.ReadWrite;
import com.gopay.common.util.SendMail;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.mail.MessagingException;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class CmbB2bQueryNtnstqryHelper {
    private final static Logger logger = LoggerFactory.getLogger(CmbB2bQueryNtnstqryHelper.class);

    public static String cmbexcelPath;

    private HttpTransport transport;

    private static String payAcct;

    public String getCmbexcelPath() {
        return cmbexcelPath;
    }

    public void setCmbexcelPath(String cmbexcelPath) {
        this.cmbexcelPath = cmbexcelPath;
    }

    /**
     * 发送邮件
     *
     * @param sendmain
     * @param fileNameExcel
     * @param excel_Path
     */
    public static void sendMessage(CmbDownLoadMessage sendmain, String fileNameExcel, String excel_Path) {

        try {
            if (sendmain != null) {
                List sendFile = new ArrayList();
                List names = new ArrayList();
                List ccList = Arrays.asList(sendmain.getCc().split(",")); //获取多个抄送人
                names.add(fileNameExcel);
                //附件标题
                String subject = "招商对账文件明细";

                logger.info("CcbBcdlCorpDccQueryHelper  fileNameExcel 路径:" + fileNameExcel + "excel_Path路径:" + excel_Path);
                // 附件内容
                String messageText = DateUtils.format(new Date(), "yyyy-MM-dd") + ": 招商对账文件请您见附件查收!" + fileNameExcel;
                for (int i = 0; i < names.size(); i++) {
                    sendFile.add(excel_Path + (String) names.get(i));
                }
                logger.info("发送邮件相关接收人信息:" + sendmain.toString());
                SendMail.sendMessage(sendmain.getHost(), sendmain.getSender(),
                        sendmain.getUsername(), sendmain.getPassword(),
                        sendmain.getReceiver(), subject, messageText, "text/html;charset=gb2312", ccList,
                        sendFile, names);


                logger.info("CmbB2bQueryNtnstqryHelper  招商对账明细邮件发送成功!");
            } else {
                logger.info("CmbB2bQueryNtnstqryHelper   招商对账明细邮件收件人信息为空,不发送信息!");
            }
        } catch (MessagingException e) {
            logger.error("CmbB2bQueryNtnstqryHelper 招商对账文件明细发送邮件失败!", e);
            e.printStackTrace();
            ;

        }

    }

    /**
     * 上午 下午转换
     *
     * @return
     */
    public static String getGregorianCalendar() {
        GregorianCalendar ca = new GregorianCalendar();
        //结果为“0”是上午 结果为“1”是下午
        String AM_PM = "";
        if (ca.get(GregorianCalendar.AM_PM) == 0) {
            AM_PM = "AM";
        } else {
            AM_PM = "PM";
        }
        return AM_PM;
    }

    public static Map<String, Object> getResulXml(String resulXml, String type) {
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            SAXReader reader = new SAXReader();
            //将字符串转换为
            Document doc = reader.read(new ByteArrayInputStream(resulXml.getBytes("GBK")));
            //获取xml文件的根节点
            Element rootElement = doc.getRootElement();
            //定义一个Element用于遍历
            Element fooElement;
            if (type.equals("INFO")) {
                for (Iterator i = rootElement.elementIterator("INFO"); i.hasNext(); ) {
                    fooElement = (Element) i.next();
                    map.put("RETCOD", fooElement.elementText("RETCOD"));
                    map.put("ERRMSG", fooElement.elementText("ERRMSG"));
                }
                return map;
            }
            if (StringUtils.equals(type, "NTRBPTRSZ1")) {
                for (Iterator i = rootElement.elementIterator("NTRBPTRSZ1"); i.hasNext(); ) {
                    fooElement = (Element) i.next();
                    map.put("COTFLG", fooElement.elementText("COTFLG"));
                    //每页的条数
                    map.put("TRSSEQ", fooElement.elementText("TRSSEQ"));
                }
                return map;
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 传值
     *
     * @param param
     * @return
     */
    public static CmbDownLoadMessage getMsg(String param) {
        String[] ob = param.split("/");
        CmbDownLoadMessage cmdDownLoadmsg = new CmbDownLoadMessage();
        if (ob != null) {
            for (int i = 0; i < ob.length; i++) {
                cmdDownLoadmsg.setHost(ob[0]);
                cmdDownLoadmsg.setSender(ob[1]);
                cmdDownLoadmsg.setUsername(ob[2]);
                cmdDownLoadmsg.setPassword(ob[3]);
                cmdDownLoadmsg.setReceiver(ob[4]);
                cmdDownLoadmsg.setCc(ob[5]);
                cmdDownLoadmsg.setDateTypes(ob[6]);
                cmdDownLoadmsg.setQuerySize(Integer.valueOf(ob[7]));
            }
        }
        return cmdDownLoadmsg;
    }


    public static boolean getExcel(CmbDownLoadMessage cmdDownLoadmsg, String fileNamePathExcel, String fileNamePathXML, String excel_Path, String fileNameExcel) {
        //先判断exce是否存在,存在则直接发送邮件,不需要调用查询银行接口
        File file = new File(fileNamePathExcel);
        //先判断txt是否存在,存在则直接发送邮件,不需要调用查询银行接口
        File fileXml = new File(fileNamePathXML);
        if (fileXml.exists()) {
            if (!file.exists()) {
                //组装数据包装成excel格式
                exportFeedBack(excel_Path, fileNamePathExcel, fileNameExcel, fileNamePathXML);
            }
            CmbB2bQueryNtnstqryHelper.sendMessage(cmdDownLoadmsg, fileNameExcel, excel_Path);
            logger.info("CmbB2bQueryNtnstqryHelper  直接发送,早已生成excel格式数据信息");
            return true;
        }
        return false;
    }

    public static String buildQuerqryxReqyXml(CmbBcdlMessage msg, String loginName, int i) {
        CmbNtnstqryxReq req = new CmbNtnstqryxReq();
        TransReqQueryInfo info = new TransReqQueryInfo();
        info.setFunnam("GetTransInfoEX");
        info.setDattyp("2");
        info.setLgnnam(msg.getLoginName());
        req.setTransReqQueryInfo(info);
        TransReqQueryNtnstqryx reqx = new TransReqQueryNtnstqryx();
        //账号
        reqx.setAccnbr(payAcct);
        //分行号
        reqx.setBbknbr("10");
        reqx.setCbbknbr("北京");
        //起始日期
        reqx.setTrsdat(msg.getOrderDate());
        reqx.setTrsseq(String.valueOf(i));
        req.setTransReqQueryNtnstqryx(reqx);
        XStream xs = new XStream();
        xs.autodetectAnnotations(true);
        xs.processAnnotations(CmbNtnstqryxReq.class);
        OutputStream output = new ByteArrayOutputStream();
        xs.marshal(req, new CompactWriter(new OutputStreamWriter(output)));
        String plainStr = output.toString();
        return plainStr;
    }

    public static HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, String[][] values, HSSFWorkbook wb) {
        try {
            // 第一步，创建一个webbook，对应一个Excel文件
            if (wb == null) {
                wb = new HSSFWorkbook();
            }
            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet sheet = wb.createSheet(sheetName);
            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
            HSSFRow row = sheet.createRow(0);
            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFCellStyle style = wb.createCellStyle();
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式

            HSSFCell cell = null;
            //创建标题
            for (int i = 0; i < title.length; i++) {
                cell = row.createCell(i);
                cell.setCellValue(title[i]);
                cell.setCellStyle(style);
            }
            //创建内容
            for (int i = 0; i < values.length; i++) {
                row = sheet.createRow(i + 1);
                for (int j = 0; j < values[i].length; j++) {
                    row.createCell(j).setCellValue(values[i][j]);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wb;
    }

    /**
     * @param fileNamePathExcel excel路径
     * @param fileNameExcel     exce文件名称
     */
    public static void exportFeedBack(String excexPath, String fileNamePathExcel, String fileNameExcel, String fileNamePathXML) {
        List<TransResQueryNtnstqryz> orderList = new ArrayList<TransResQueryNtnstqryz>();
        Object[] resXml = ReadWrite.read(fileNamePathXML).toString().split("/-/");
        for (Object obj : resXml) {
            if (!obj.equals("\r\n")) {
                try {
                    SAXReader reader = new SAXReader();
                    //将字符串转换为
                    Document doc = reader.read(new ByteArrayInputStream(obj.toString().getBytes("GBK")));
                    //获取xml文件的根节点
                    Element rootElement = doc.getRootElement();
                    //定义一个Element用于遍历
                    Element fooElement;
                    //遍历所有名叫“VALUE”的节点
                    for (Iterator i = rootElement.elementIterator("NTQTSINFZ"); i.hasNext(); ) {
                        fooElement = (Element) i.next();
                        TransResQueryNtnstqryz res = new TransResQueryNtnstqryz();
                        //交易日
                        res.setEtydat(fooElement.elementText("ETYDAT"));
                        //交易时间
                        res.setEtytim(fooElement.elementText("ETYTIM"));
                        //起息日
                        res.setVltdat(fooElement.elementText("VLTDAT"));
                        //交易类型
                        res.setTrscod(fooElement.elementText("TRSCOD"));
                        //借贷标记	C（1）	C:贷；D:借
                        String amtcdr = fooElement.elementText("AMTCDR");
                        //借方金额
                        res.setTrsamtd(amtcdr.equals("D") ? fooElement.elementText("TRSAMTD") : "");
                        //贷方金额
                        res.setC_trsamt(amtcdr.equals("C") ? fooElement.elementText("TRSAMTC") : "");
                        //余额
                        res.setTrsblv(fooElement.elementText("TRSBLV"));
                        //摘要
                        res.setNaryur(fooElement.elementText("NARYUR"));
                        //流水号
                        res.setRefnbr(fooElement.elementText("REFNBR"));
                        //流程实例号
                        res.setReqnbr(fooElement.elementText("REQNBR"));
                        //业务名称
                        res.setBusnam(fooElement.elementText("BUSNAM"));
                        //用途
                        res.setNusage(fooElement.elementText("NUSAGE"));
                        //业务参考号
                        res.setYurref(fooElement.elementText("YURREF"));
                        //业务摘要
                        res.setBusnar(fooElement.elementText("BUSNAR"));
                        //其它摘要
                        res.setOtrnar(fooElement.elementText("OTRNAR"));
                        //收/付方分行名
                        res.setRpybnk(fooElement.elementText("RPYBNK"));
                        //收/付方名称
                        res.setRpynam(fooElement.elementText("RPYNAM"));
                        //收/付方帐号
                        res.setRpyacc(fooElement.elementText("RPYACC"));
                        //收/付方开户行行号
                        res.setRpybbn(fooElement.elementText("RPYBBN"));
                        //收/付方开户行名
                        res.setRpybnk(fooElement.elementText("RPYBNK"));
                        //收/付方开户行地址
                        res.setRpyadr(fooElement.elementText("RPYADR"));
                        //母/子公司帐号分行名    ==母/子公司所在地区
                        res.setC_gsbbbk(fooElement.elementText("C_GSBBBK"));
                        //母/子公司帐号
                        res.setGsbacc(fooElement.elementText("GSBACC"));
                        //母/子公司名称
                        res.setGsbnam(fooElement.elementText("GSBNAM"));
                        //信息标志    用于标识收/付方帐号和母/子公司的信息。为空表示付方帐号和子公司；
                        // 为“1”表示收方帐号和子公司；为“2”表示收方帐号和母公司；为“3”表示原收方帐号和子公司
                        res.setInfflg(fooElement.elementText("INFFLG"));
                        //有否附件信息
                        res.setC_athflg(fooElement.elementText("C_ATHFLG"));
                        //冲帐标志  *为冲帐，X为补帐（冲账交易与原交易借贷相反）
                        res.setRsvflg(fooElement.elementText("RSVFLG"));
                        //扩展摘要
                        res.setNarext(fooElement.elementText("NAREXT"));
                        //交易分析码
                        res.setTrsanl(fooElement.elementText("TRSANL"));
                        //票据号
                        res.setChknbr(fooElement.elementText("CHKNBR"));
                        //商务支付订单号
                        res.setRefsub(fooElement.elementText("REFSUB"));
                        //内部编号

                        //放入集合中去
                        orderList.add(res);
                    }
                } catch (Exception e) {
                    e.printStackTrace();

                }

            }
        }

        //文件名称
        String fileName = fileNameExcel;
        String[] title = new String[]{"交易日", "交易时间", "起息日", "交易类型", "借方金额", "贷方金额", "余额", "摘要", "流水号", "流程实例号", "业务名称",
                "用途", "业务参考号", "业务摘要", "其它摘要", "收/付方分行名", "收/付方名称", "收/付方帐号", "收/付方开户行行号", "收/付方开户行名", "收/付方开户行地址", "母/子公司帐号分行名",
                "母/子公司帐号", "母/子公司名称", "信息标志", "有否附件信息", "冲帐标志", "扩展摘要", "交易分析码", "票据号", "商务支付订单号", "内部编号"};
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int size = orderList.size();
        String[][] values = new String[size][];
        int j = 0;
        for (int i = 0; i < orderList.size(); i++) {
            //将对象内容转换成string
            TransResQueryNtnstqryz body = orderList.get(i);
            //循环便利
            values[j] = new String[title.length];
            //交易日
            values[j][0] = body.getEtydat();
            //交易时间
            values[j][1] = body.getEtytim();
            //起息日
            values[j][2] = body.getVltdat();
            //交易类型
            values[j][3] = CmbUtil.getMap(body.getTrscod()).toString();
            //借方金额
            values[j][4] = body.getTrsamtd();
            //贷方金额
            values[j][5] = body.getC_trsamt();
            //余额
            values[j][6] = body.getTrsblv();
            //摘要
            values[j][7] = body.getNaryur();
            //流水号
            values[j][8] = body.getRefnbr();
            //流程实例号
            values[j][9] = body.getReqnbr();
            //业务名称
            values[j][10] = body.getBusnam();
            //业务名称
            values[j][11] = body.getNusage();
            //业务参考号
            values[j][12] = body.getYurref();
            //业务摘要
            values[j][13] = body.getBusnar();
            //其它摘要
            values[j][14] = body.getOtrnar();
            //收/付方分行名
            values[j][15] = body.getRpybnk();
            //收/付方名称
            values[j][16] = body.getRpynam();
            //收/付方帐号
            values[j][17] = body.getRpyacc();
            //收/付方开户行行号
            values[j][18] = body.getRpybbn();
            //收/付方开户行名
            values[j][19] = body.getRpybnk();
            //收/付方开户行地址
            values[j][20] = body.getRpyadr();
            //母/子公司帐号分行名    ==母/子公司所在地区
            values[j][21] = body.getC_gsbbbk();
            //母/子公司帐号
            values[j][22] = body.getGsbacc();
            //母/子公司名称
            values[j][23] = body.getGsbnam();
            //信息标志    用于标识收/付方帐号和母/子公司的信息
            // 为“1”表示收方帐号和子公司；为“2”表示收方帐号和
            values[j][24] = body.getInfflg();
            //有否附件信息
            values[j][25] = body.getC_athflg();
            //冲帐标志  *为冲帐，X为补帐（冲账交易与原交易借贷相反）
            values[j][26] = body.getRsvflg();
            //扩展摘要
            values[j][27] = body.getNarext();
            //交易分析码
            values[j][28] = body.getTrsanl();
            //票据号
            values[j][29] = body.getChknbr();
            //商务支付订单号
            values[j][30] = body.getRefsub();
            //内部编号
            values[j][31] = "";
            j++;
//            }
        }
        HSSFWorkbook wb = getHSSFWorkbook(fileName, title, values, null);
        //将文件存到指定位置
        try {
            File filemk = new File(excexPath);
            //创建目录
            if (!filemk.exists()) {
                filemk.mkdirs();
            }
            File file = new File(excexPath + fileName);
            OutputStream out = new FileOutputStream(file, true);
            wb.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public HttpTransport getTransport() {
        return transport;
    }

    public void setTransport(HttpTransport transport) {
        this.transport = transport;
    }

    public String getPayAcct() {
        return payAcct;
    }

    public void setPayAcct(String payAcct) {
        this.payAcct = payAcct;
    }
}
